from common.db import models
from apps.user.models import WithdrawCash
from django.contrib.postgres.fields import JSONField
from apps.storage.models import PublicFile
from decimal import Decimal
from tuntun.settings import GIFT_EXPIRE_TIME


# Create your models here.

class ExpressCompany(models.Model):
    init_data = [
        {"name": "中通快递", "code": "zhongtong"},
    ]
    name = models.CharField("快递公司名")
    code = models.CharField("快递公司编号")
    kefu_phone = models.CharField('电话', blank=True, null=True)

    def __str__(self):
        return self.name


class Order(models.Model):
    """
    Order
        amount 该订单买家支付的总金额
        packages_amount 该订单包装总金额
        计算规则：
            预售/正常交易：ji
                packages_amount = 0
                amount = 所有SubOrder的amount总和 + packages_amount
                扣除给平台的总额 = 所有SubOrder的存仓费手续费物流费等费用总额
            提仓：
                packages_amount = 0 或 总价
                所有SubOrder的amount = 0
                amount = 所有SubOrder的amount总和 + packages_amount + 所有SubOrder的存仓费手续费物流费等费用总额
    """

    class Meta:
        verbose_name = verbose_name_plural = '订单'
        ordering = ('-add_timestamp',)

    PaymentMethod = WithdrawCash.AccountType

    class Status(models.Choices):
        CREATED = "已创建"
        PAYED = "已支付"
        GIFT_BE_REJECTED = "赠送已被拒绝"
        # GIFT_BE_RECEIVED = "赠送已被接受"
        # GIFT_REPO_COST_BE_SETTLED = "赠送后仓储费已结算"
        FINISHED = "已完成"
        EXPIRED = "已过期"
        CANCELED = "取消"
        """
        交易=CREATED>PAYED>FINISHED
        提仓=CREATED>PAYED-FINISHED
        赠送=CREATED-GIFT_BE_REJECTED
        """

    class CreateType(models.Choices):
        PRE_SALE_BUY_IN = "预售买入"
        MARKET_BUY_IN = "茶市买入"
        # DIRECTIONAL_SELL_OUT = "定向卖出"
        # DIRECTIONAL_BUY_IN = "定向买入"
        # MARKET_AUTO_MATCH = "茶市自动匹配"
        TAKE_OUT = "提仓"

    no = models.CharField("订单号", max_length=64)
    amount = models.DecimalField("订单总金额", max_digits=10, decimal_places=2)
    payment_method = models.CharField("支付方式", choices=PaymentMethod.get_choices())
    status = models.CharField("状态", choices=Status.get_choices(), default=Status.CREATED.name)
    expire_at = models.FloatField("过期时间")
    buyer_user_id = models.CharField("买家ID")
    address_id = models.CharField("地址ID", blank=True, null=True)
    address_mobile = models.CharField("手机号", blank=True, null=True)
    address_name = models.CharField("收件人", blank=True, null=True)
    address_full_address = models.CharField("完整地址", blank=True, null=True)
    as_gift = models.BooleanField("是否赠送", default=False)  # 仅赠送时这个字段有意义，status才会有BE_GIFTED状态
    as_gift_multiple = models.BooleanField('赠送多人', default=False)
    as_gift_pre_pay_repo_cost = models.BooleanField("预付存仓费", default=False)
    as_gift_pre_pay_repo_cost_amount = models.DecimalField("预付仓储费金额", max_digits=10, decimal_places=2,
                                                           default=Decimal('0.00'))
    packages_amount = models.DecimalField("包装总金额", max_digits=10, decimal_places=2)
    express_company = models.ForeignKey(ExpressCompany, verbose_name='快递公司', blank=True, null=True)
    express_no = models.CharField("快递单号", blank=True, null=True)
    express_info = JSONField("快递信息", blank=True, null=True)
    express_info_update_time = models.DateTimeField("快递信息更新时间", blank=True, null=True)
    #
    repo_amount = models.DecimalField("仓储费", max_digits=10, decimal_places=2)
    repo_preferential_amount = models.DecimalField("减免仓储费", max_digits=10, decimal_places=2)
    repo_real_pay_amount = models.DecimalField("仓储费实收", max_digits=10, decimal_places=2)
    procedure_amount = models.DecimalField("手续费", max_digits=10, decimal_places=2)
    procedure_preferential_amount = models.DecimalField("减免手续费", max_digits=10, decimal_places=2)
    procedure_real_pay_amount = models.DecimalField("手续费实收", max_digits=10, decimal_places=2)
    logistics_amount = models.DecimalField("物流费", max_digits=6, decimal_places=2)
    logistics_preferential_amount = models.DecimalField("减免物流费", max_digits=6, decimal_places=2)
    logistics_real_pay_amount = models.DecimalField("物流费实收", max_digits=6, decimal_places=2)
    create_type = models.CharField("创建类型", choices=CreateType.get_choices(), default=CreateType.PRE_SALE_BUY_IN.name)
    post_finished_done = models.BooleanField('已经预处理', default=False)
    #
    use_take_out_free_postage_right_id = models.CharField(verbose_name='使用包邮权益记录', blank=True, null=True)

    def __str__(self):
        return '%s-%s-%s' % (self.buyer_user, self.no, self.amount)

    @property
    def product(self):
        from apps.product.models import Product
        first_sub_order = SubOrder.objects.filter(order=self).first()
        if not first_sub_order:
            return None
        return Product.objects.filter(pk=first_sub_order.product_id).first()

    @property
    def product_name(self):
        return self.product.name if self.product else ''

    @property
    def status_display(self):
        return getattr(Order.Status, self.status).value

    @property
    def create_type_display(self):
        return getattr(SubOrder.CreateType, self.create_type).value

    @property
    def to_seller_user_amount(self):
        return self.amount - self.repo_real_pay_amount - self.procedure_real_pay_amount

    @property
    def trade_datetime(self):
        import time
        return time.strftime(self.datetime_format, time.localtime(self.update_timestamp))

    def get_pay_expire_at(self):
        import time
        return time.strftime(self.datetime_format, time.localtime(self.expire_at))

    def get_gift_expire_at(self):
        import time
        return time.strftime(self.datetime_format, time.localtime(self.update_timestamp + GIFT_EXPIRE_TIME))

    @property
    def market_order(self):
        from apps.product.models import MarketOrder
        first_sub_order = SubOrder.objects.filter(order=self).first()
        return MarketOrder.objects.filter(id=first_sub_order.market_order_id).first()

    @property
    def buyer_user(self):
        from apps.user.models import User
        return User.objects.get(pk=self.buyer_user_id)

    @property
    def seller_user(self):
        from apps.user.models import User
        first_sub_order = SubOrder.objects.filter(order=self).first()
        if not first_sub_order:
            return None
        return User.objects.get(pk=first_sub_order.seller_user_id)

    @classmethod
    def make_order_no(cls, mobile):
        """
        订单号生成
        # 当前用户手机号 379位+4位随机数+日期8
        :param mobile:
        :return:
        """
        from tuntun.settings import PAY_EXPIRE_TIME, ORDER_MOBILE_STR, RANDOM_LEN, PRE_SALE_BLOCK_LOCK_TIME
        import time
        from random import choice
        # 手机号
        mobile_str = ""
        for ms in ORDER_MOBILE_STR:
            mobile_str += mobile[ms:ms + 1]

        # 日期
        date = time.strftime("%Y%m%d")

        # 随机数
        seeds = "1234567890"
        random_str = []
        for i in range(RANDOM_LEN):
            random_str.append(choice(seeds))
        ran = "".join(random_str)

        # 返回
        no = mobile_str + date + ran
        return no

    def get_as_gift_payment_amount(self):
        a = self.repo_amount + self.as_gift_pre_pay_repo_cost_amount - self.repo_preferential_amount
        if a < Decimal('0.00'):
            a = Decimal('0.00')
        return a

    @property
    def grow_coins(self):
        from apps.product.models import Product, GrowCoinRecord

        suborders = SubOrder.objects.filter(order_id=self.id)
        first_sub_order = suborders.first()
        product = Product.objects.filter(id=first_sub_order.product_id).first()

        tea_weight = product.weight * suborders.count()
        if self.create_type == self.CreateType.PRE_SALE_BUY_IN.name:  # 预售买入
            # 更新成长值
            geted_grow_coins = int(tea_weight / 100) * getattr(GrowCoinRecord.Amount,
                                                               GrowCoinRecord.HappenType.TUN.name).value
            return geted_grow_coins.__str__()
        elif self.create_type == self.CreateType.MARKET_BUY_IN.name:  # 茶市买入
            # 囤茶获取成长值
            tun_geted_grow_coins = int(tea_weight / 100) * getattr(GrowCoinRecord.Amount,
                                                                   GrowCoinRecord.HappenType.TUN.name).value
            # 交易获取成长值
            buyer_trade_geted_grow_coins = getattr(GrowCoinRecord.Amount, GrowCoinRecord.HappenType.TRADE.name).value
            return (tun_geted_grow_coins + buyer_trade_geted_grow_coins).__str__()


class OrderPackage(models.Model):
    order = models.ForeignKey(Order, verbose_name='主订单', on_delete=models.CASCADE)
    package_id = models.CharField("包装ID")
    name = models.CharField(verbose_name='包装名称')
    price = models.DecimalField("包装价格", max_digits=10, decimal_places=2)
    avatar_public_file_id = models.CharField("Avatar公开文件ID", max_length=64, blank=True, null=True)
    count = models.IntegerField("包装数量", default=0)

    @property
    def avatar_public_file(self) -> PublicFile:
        return PublicFile.objects.get(id=self.avatar_public_file_id)

    @property
    def avatar(self):
        return self.avatar_public_file.url


class SubOrder(models.Model):
    """Sub Order"""

    class CreateType(models.Choices):
        PRE_SALE_BUY_IN = "预售买入"
        MARKET_BUY_IN = "茶市买入"
        # DIRECTIONAL_SELL_OUT = "定向卖出"
        # DIRECTIONAL_BUY_IN = "定向买入"
        # MARKET_AUTO_MATCH = "茶市自动匹配"
        TAKE_OUT = "提仓"

    order = models.ForeignKey(Order, verbose_name='主订单', on_delete=models.CASCADE)
    goods_block_id = models.CharField("商品区块链ID")  # goods_block_id
    product_id = models.CharField("产品ID", blank=True, null=True)
    product_name = models.CharField("产品名", blank=True, null=True)
    goods_block_repo_id = models.CharField("仓库ID")
    goods_block_repo_name = models.CharField("仓库名")
    store_unit_id = models.CharField("存储单元ID", blank=True, null=True)
    price_per_100g_1d = models.DecimalField("元/1g/每日", max_digits=8, decimal_places=4)
    amount = models.DecimalField("金额", max_digits=10, decimal_places=2)
    seller_user_id = models.CharField("卖家ID", blank=True, null=True)
    market_order_id = models.CharField("隶属挂单ID", blank=True, null=True)
    create_type = models.CharField("创建类型", choices=CreateType.get_choices())
    repo_amount = models.DecimalField("仓储费", max_digits=10, decimal_places=2)
    repo_cost_start_datetime = models.DateTimeField("费用开始时间", blank=True, null=True)
    repo_cost_end_datetime = models.DateTimeField("费用结束时间", blank=True, null=True)
    #
    goods_block_to_repo_id = models.CharField("仓库ID", blank=True, null=True)
    goods_block_to_repo_name = models.CharField("仓库名", blank=True, null=True)

    @property
    def goods_block(self):
        from apps.product.models import GoodsBlock
        gb = GoodsBlock.objects.get(pk=self.goods_block_id)
        return gb
    #
    def goods_block_unique_code(self):
        from apps.product.models import GoodsBlock
        gb = GoodsBlock.objects.get(pk=self.goods_block_id)
        return gb.unique_code


    def goods_block_repo_no(self):
        from apps.product.models import GoodsBlock
        from apps.repo.models import StoreUnitThree
        return StoreUnitThree.objects.get(pk=self.goods_block.store_unit_id).repo_no


    def get_storage_repo_days(self):
        td = self.repo_cost_end_datetime - self.repo_cost_start_datetime
        return td.days

    @property
    def buyer_user_id(self):
        return self.order.buyer_user_id


class SubOrderComment(models.Model):
    user_id = models.CharField("用户ID", max_length=64)
    sub_order = models.ForeignKey(SubOrder, verbose_name='子订单', on_delete=models.CASCADE)
    content = models.TextField("内容")


class SubOrderCommentPictures(models.Model):
    """
    订单评论附图
    """
    sub_order_comment = models.ForeignKey(SubOrder, verbose_name='订单评论', on_delete=models.CASCADE)
    picture_public_file_id = models.CharField("公开文件ID", max_length=64)
    order = models.IntegerField("顺序")


class Payment(models.Model):
    """
    支付记录表
    """

    class Status(models.Choices):
        WAITPAY = "待支付"
        PAYED = '已支付'
        CANCELED = "已取消"

    class PType(models.Choices):
        TRADE = '交易'
        CERT = '认证'
        RECHARGE = '充值'

    class CallbackType(models.Choices):
        APP = 'App'
        PROVIDER = '供应商'

    PaymentMethod = WithdrawCash.AccountType

    ptype = models.CharField(verbose_name='支付类型', choices=PType.get_choices(), default=PType.TRADE.name)
    order = models.ForeignKey(Order, verbose_name='主订单', on_delete=models.CASCADE)
    buyer_user_id = models.CharField("买家ID")
    payment_method = models.CharField("支付方式", choices=PaymentMethod.get_choices())
    status = models.CharField(verbose_name='状态', default=Status.WAITPAY.name)
    water_no = models.CharField(verbose_name='支付流水号(alipay-trade_no wx-water_no)', blank=True, null=True)
    settlement_total_fee = models.DecimalField("实付金额", max_digits=10, decimal_places=2)

    provider_resp = JSONField("供应商返回", default={})

    callbacked = models.BooleanField(verbose_name='是否已被回调', default=False)
    callback_type = models.CharField(verbose_name='回调类型', default=CallbackType.APP.name)

    # callback_data = models.TextField(verbose_name='回调数据', blank=True, null=True)

    @property
    def order_amount(self):
        return self.order.amount
